/*
 *  ParticleSystem.cpp
 *  GLRender
 *
 *  Created by Matthias on 5/26/10.
 *  Copyright 2010 __MyCompanyName__. All rights reserved.
 *
 */

#include "ParticleSystem.h"
#include <QtOpenGL>
#define MAX_FUEL 500

ParticleSystem::ParticleSystem(const RGBd &color, const int quantity, const int radius){
	this->color = color;
	this->quantity = quantity;
	this->radius = radius;
	
	for(int i=0; i< quantity; i++){
		particles.push_back(createParticle());
	}
}

void
ParticleSystem::setCenter(const Point3d &center){
	this->center = center;
}

void
ParticleSystem::setDirection(const Point3d &dir){
	this->speed = dir;
	//this->speed.normalize();
	this->speed/=40.0;
}

double
ParticleSystem::newRandom(){
	return (2.0 * radius * ((double) rand()) / ((double) RAND_MAX)) - radius;
}

Point3d
ParticleSystem::newPosition(){
	double x, y, z;
	x = newRandom()+center.x();
	y = newRandom()+center.y();
	z = newRandom()+center.z();
	
	return Point3d(x, y, z);
}

const particlePart
ParticleSystem::createParticle(){
	particlePart partialParticle;
	
	partialParticle.position = newPosition();
	partialParticle.speed = this->speed;
	partialParticle.fuel = (100.0 * ((double) rand()) / ((double) RAND_MAX)) + MAX_FUEL-100.0;
	partialParticle.color = this->color;
	
	return partialParticle;
}

void
ParticleSystem::displayPoint(){
	glPointSize(0.1f);
	glEnable(GL_POINT_SMOOTH);
	glBegin(GL_POINTS);
	
	std::vector <particlePart>::iterator it = particles.begin();
	
	while(it != particles.end()){
		if(it->fuel > 0){
			glColor4d(it->color.r(), it->color.g(), it->color.b(), 0.2);
			glVertex3d(it->position.x(), it->position.y(), it->position.z());
			it->position += this->speed;
			it->fuel--;
			it++;
		}else{
			it = particles.erase(it);
			particles.push_back(createParticle());
		}
	}
	glEnd();
	glDisable(GL_POINT_SMOOTH);
}


void
ParticleSystem::display(){
	glDisable(GL_LIGHTING);
	glEnable (GL_BLEND); 
	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glClear(GL_ACCUM_BUFFER_BIT);

	glPushMatrix();
	int max = 40;
	for(int i = 0; i < max; i++) {
		displayPoint();
        glAccum(GL_ACCUM, 1.f/((float)max-i));
	} 
	glAccum(GL_RETURN, 1.f);
	
	glPopMatrix();
	glDisable(GL_BLEND);
	glEnable(GL_LIGHTING);
	
}

